home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 August: Tool Chest / Dev.CD Aug 95 TC / Dev.CD Aug 95 TC.toast / Sample Code / Snippets / Toolbox / MovableModal / MModal 7.0.c next >
Encoding:
C/C++ Source or Header  |  1995-02-10  |  23.7 KB  |  676 lines  |  [TEXT/MPS ]

  1. /* MModal.c */
  2. /* The simplest C System 7 shell application */
  3. /* Modified to show a simple Moveable Modal window */
  4.  
  5. /* This shell can be very handy for debugging and testing things */
  6. /* Add menu items, add dialogs, add controls, or whatever else you need */
  7. /* This sample contains basic application startup and event loop handling, */
  8. /* add more features as your needs increase. */
  9. /* This sample is High Level Event aware, so you can send and receive AppleEvents */
  10. /* from this application */
  11. /* Written by C.K. Haun <TR> */
  12. /* Apple Developer Tech Support */
  13. /* October 1991, Tokyo, Japan */
  14. /* Of course, Copyright 1991-1992, Apple Computer Inc. */
  15.  
  16.  
  17. #include <Types.h>
  18. #include <memory.h>
  19. #include <Packages.h>
  20. #include <Errors.h>
  21. #include <quickdraw.h>
  22. #include <fonts.h>
  23. #include <dialogs.h>
  24. #include <windows.h>
  25. #include <menus.h>
  26. #include <events.h>
  27. #include <OSEvents.h>
  28. #include <Desk.h>
  29. #include <diskinit.h>
  30. #include <OSUtils.h>
  31. #include <resources.h>
  32. #include <toolutils.h>
  33. #include <AppleEvents.h>
  34. #include <EPPC.h>
  35. #include <GestaltEqu.h>
  36. #include <PPCToolbox.h> 
  37. #include <Processes.h>
  38. #include <Balloons.h>
  39. #include <ALiases.h>
  40. #include <Processes.h>
  41. #include <StandardFile.h>
  42. #include <Folders.h>
  43.  
  44. /* prototypes */
  45. void OpenMovable(void);
  46. void CloseMovable(void);
  47. void InitalizeApp(void);
  48. void DoDiskEvents(long dinfo);                              /* hi word is error code, lo word is drive number */
  49. void DrawMain(WindowPtr drawIt);
  50. void DrawMain2(WindowPtr drawIt);
  51. void DrawMovable(WindowPtr drawIt);
  52. Boolean DoSelected(long val);
  53. void InitAEStuff(void);
  54. void DoHighLevel(EventRecord *AERecord);
  55. void DoDaCall(MenuHandle themenu, long theit);
  56. pascal     OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  57. pascal     OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  58. pascal   OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  59. pascal     OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  60. void SampleHelpDialog(void);
  61. void SetModalButtonState(Boolean gInBackground);
  62.  
  63. /* one external */
  64. extern void _DataInit();                                    /* this is the C initialization code */
  65.  
  66. enum  {
  67.     kMBarID = 128
  68. };
  69. enum  {
  70.     kAppleMenu = 128, kFileMenu, kEditMenu, kToolsMenu
  71. };
  72. enum  {
  73.     kResumeMask = 1,                                        /* bit of message field for resume vs. suspend */
  74.     kSampHelp = 129, kAboutBox = 128, kHelpString = 128, kNewItem = 1, kOpenItem, kCloseItem, kSaveItem, kSaveAsItem, kFileBlank1,
  75.         kPageSetupItem, kPrintItem, kFileBlank2, kQuitItem, kBadSystem = 130, kGenStrings = 128, kMenuToggleStrings = 129,
  76.         kCloseButton = 128, kMyModalKind = 1000, kMyDocumentKind
  77. };
  78. enum  {
  79.     kItem1 = 1
  80. };
  81. enum  {
  82.     kCloseIt = 1, kOpenIt
  83. };
  84.  
  85. /* some globals */
  86. MenuHandle gAppleMenuHandle, gFileMenuHandle, gEditMenuHandle, gToolMenuHandle;
  87. Boolean gQuit, gInBackground;
  88. EventRecord gERecord;
  89. Point gSavedPoint;
  90. Boolean gSavedPos;
  91. AEDesc gTheAddress;
  92. ProcessSerialNumber gOurSN;
  93. short gHelpItem;
  94. /* this is our global to tell us if a movable modal is up*/
  95. Boolean gModalUp = false;
  96. unsigned long gMySleep = 30;
  97.  
  98. #ifdef powerc
  99.    QDGlobals    qd;
  100. #endif
  101.  
  102. #pragma segment Main
  103. main()
  104. {
  105.     WindowPtr twindow;
  106.     UnloadSeg((Ptr)_DataInit);                              /* throw out setup code */
  107.     InitalizeApp();
  108.     UnloadSeg((Ptr)InitalizeApp);                           /* get rid of my initialization code */
  109.     do {
  110.         
  111.         WaitNextEvent(everyEvent, &gERecord, gMySleep, nil);
  112.         switch (gERecord.what) {
  113.             ProcPtr drawProc;
  114.             short tempKind;
  115.             case nullEvent:
  116.                 /* no nul processing in this sample */
  117.                 break;
  118.                 
  119.             case updateEvt:
  120.                 tempKind = ((WindowPeek)gERecord.message)->windowKind;
  121.                 /* Mkae sure it's my window before I jump through the refCon */
  122.                 /* Why, since DA's have they're own layer in 7.0? */
  123.                 /* BECAUSE there are other people in the universe who will */
  124.                 /* add things to your windowList.BalloonWriter, for example, */
  125.                 /* so you still need to be careful */
  126.                 if (tempKind == kMyModalKind || tempKind == kMyDocumentKind) {
  127.                     /* get the drawing proc from the refCon */
  128.                     drawProc = (ProcPtr)GetWRefCon((WindowPtr)gERecord.message);
  129.                     /* jump to it */
  130.                     drawProc((WindowPtr)gERecord.message);
  131.                 }
  132.                 break;
  133.                 
  134.             case mouseDown:
  135.                 /* first see where the hit was */
  136.                 /* When you first think about the Movable Modal issue, you may*/
  137.                 /* say to yerself "Hey!if there's a mouseDown all I have to do is*/
  138.                 /* see if it's in the portRect of the front window, and SysBeep if it isn't!" */
  139.                 /* Nah, too easy.Remember, you want a user to be able to switch out */
  140.                 /* of your application when a movable modal is up, so you still need */
  141.                 /* to call FindWindow and see if it was a hit in the desktop, other*/
  142.                 /* app window (same as desktop), or in the Help or Application menus. */
  143.                 /* So, we just check our gModalUp flag in any place where */
  144.                 /* window positions may shift, and sysbeep elsewhere */
  145.                 
  146.                 switch (FindWindow(gERecord.where, &twindow)) {
  147.                     
  148.                     case inDesk:                            /* if they hit in desk, then the process manager */
  149.                         break;                              /* will switch us out, we don't need to do anything */
  150.                         
  151.                     case inMenuBar:
  152.                         /* let Help and Application menus happen always */
  153.                         DoSelected(MenuSelect(gERecord.where));
  154.                         break;
  155.                         
  156.                     case inSysWindow:
  157.                         /* pass to the system */
  158.                         SystemClick(&gERecord, twindow);
  159.                         break;
  160.                         
  161.                     case inContent:
  162.                         /* Handle content and control clicks here */
  163.                         if (twindow != FrontWindow()) {
  164.                             if (!gModalUp) {
  165.                                 SelectWindow(twindow);      /* select the window */
  166.                                 SetPort(twindow);
  167.                             } else {
  168.                                 SysBeep(1);                 /* complain because they hit a back window with MM up */
  169.                             }
  170.                         } else {
  171.                             /* control tracking or whatever.In this simple sample I */
  172.                             /* only have one control possible, so deal with it */
  173.                             Point locPoint = gERecord.where;
  174.                             ControlHandle returnedControl;
  175.                             GlobalToLocal(&locPoint);
  176.                             if (FindControl(locPoint, twindow, &returnedControl)) {
  177.                                 if (TrackControl(returnedControl, locPoint, nil)) {
  178.                                     CloseMovable();
  179.                                 }
  180.                             }
  181.                         }
  182.                         break;
  183.                         
  184.                     case inDrag:
  185.                         if (twindow != FrontWindow() && gModalUp) {
  186.                             /* don't do anything, can't drag a back window */
  187.                             SysBeep(1);
  188.                         } else {
  189.                             DragWindow(twindow, gERecord.where, &qd.screenBits.bounds);
  190.                         }
  191.                         break;
  192.                         
  193.                     case inGrow:
  194.                         /* Call GrowWindow here if you have a grow box */
  195.                         break;
  196.                         
  197.                     case inGoAway:
  198.                         /* Click in Close box */
  199.                         break;
  200.                 }
  201.             case mouseUp:
  202.                 /* don't care */
  203.                 break;
  204.                 /* same action for key or auto key */
  205.             case keyDown:
  206.             case autoKey:
  207.                 if (gERecord.modifiers & cmdKey)
  208.                     DoSelected(MenuKey(gERecord.message & charCodeMask));
  209.                 break;
  210.                 
  211.             case keyUp:
  212.                 /* don't care */
  213.                 break;
  214.                 
  215.             case diskEvt:
  216.                 /* I don't do anything special for disk events, this just passes them */
  217.                 /* to a function that checks for an error on the mount */
  218.                 DoDiskEvents(gERecord.message);
  219.                 break;
  220.                 
  221.             case activateEvt:
  222.                 /* not doing anything on activates */
  223.                 break;
  224.                 
  225.             case networkEvt:
  226.                 /* don't care */
  227.                 break;
  228.                 
  229.             case driverEvt:
  230.                 /* don't care */
  231.                 break;
  232.                 
  233.             case app4Evt:
  234.                 /* If we're switching layers and I have my MModal up, I want to */
  235.                 /* change the state of the control */
  236.                 switch ((gERecord.message >> 24) & 0x0FF) {     /* high byte of message */
  237.                     
  238.                     case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  239.                         gInBackground = (gERecord.message & kResumeMask) == 0;
  240.                         /* set dim/enable on the control */
  241.                         SetModalButtonState(gInBackground);
  242.                         break;
  243.                         
  244.                 }
  245.                 break;
  246.                 
  247.                 /* This dispatches high level events (AppleEvents, for example) */
  248.                 /* to our dispatch routine.This is NEW in the event loop for */
  249.                 /* System 7 */
  250.             case kHighLevelEvent:
  251.                 DoHighLevel(&gERecord);
  252.                 break;
  253.             default:
  254.                 break;
  255.                 
  256.         }
  257.     }
  258.             while (gQuit != true);
  259. }
  260.  
  261. /* DoDaCall opens the requested DA.It's here as a seperate routine if you'd */
  262. /* like to perform some action or just know when a DA is opened in your */
  263. /* layer.Can be handy to track memory problems when a DA is opened */
  264. /* with an Option-open */
  265. void DoDaCall(MenuHandle themenu, long theit)
  266. {
  267.     long qq;
  268.     char DAname[255];
  269.     GetMenuItemText(themenu, theit, &DAname);
  270.     qq = OpenDeskAcc(DAname);
  271. }
  272.  
  273. /* end DoDaCall */
  274.  
  275. /* DoDiskEvents just checks the error code from the disk mount, */
  276. /* and puts up the 'Format' dialog (through DIBadMount) if need be */
  277. /* You can do much more here if you care about what disks are */
  278. /* in the drive */
  279. void DoDiskEvents(long dinfo)                               /* hi word is error code, lo word is drive number */
  280. {
  281.     short hival, loval, tommy;
  282.     Point fredpoint =  {
  283.         40, 40
  284.     };
  285.     hival = HiWord(dinfo);
  286.     loval = LoWord(dinfo);
  287.     if (hival != noErr)                                     /* something happened */ {
  288.         tommy = DIBadMount(fredpoint, dinfo);
  289.     }
  290. }
  291.  
  292. /* draws my window.Pretty simple */
  293. void DrawMain(WindowPtr drawIt)
  294. {
  295.     Handle theText;
  296.     WindowPtr tempWP;
  297.     GetPort(&tempWP);
  298.     BeginUpdate(drawIt);
  299.     SetPort(drawIt);
  300.     EraseRect(&drawIt->portRect);
  301.     theText = GetResource('TEXT', 128);
  302.     if (theText) {
  303.         Rect textRect;
  304.         HLock(theText);
  305.         HUnlock(theText);
  306.         textRect = drawIt->portRect;
  307.         InsetRect(&textRect, 20, 20);
  308.         TETextBox(*theText, GetHandleSize(theText), &textRect, 0);
  309.         ReleaseResource(theText);
  310.     }
  311.     EndUpdate(drawIt);
  312.     SetPort(tempWP);
  313. }
  314. /* a second version for variety */
  315. void DrawMain2(WindowPtr drawIt)
  316. {
  317.     Handle theText;
  318.     WindowPtr tempWP;
  319.     GetPort(&tempWP);
  320.     
  321.     BeginUpdate(drawIt);
  322.     SetPort(drawIt);
  323.     EraseRect(&drawIt->portRect);
  324.     theText = GetResource('TEXT', 130);
  325.     if (theText) {
  326.         Rect textRect;
  327.         HLock(theText);
  328.         HUnlock(theText);
  329.         textRect = drawIt->portRect;
  330.         InsetRect(&textRect, 20, 20);
  331.         TETextBox(*theText, GetHandleSize(theText), &textRect, 0);
  332.         ReleaseResource(theText);
  333.     }
  334.     EndUpdate(drawIt);
  335.     SetPort(tempWP);
  336. }
  337.  
  338. /* Draws the Movable Modal window contents */
  339. void DrawMovable(WindowPtr drawIt)
  340. {
  341.     WindowPtr tempWP;
  342.     Handle theText;
  343.     BeginUpdate(drawIt);
  344.     GetPort(&tempWP);
  345.     
  346.     SetPort(drawIt);
  347.     EraseRect(&drawIt->portRect);
  348.     theText = GetResource('TEXT', 129);
  349.     if (theText) {
  350.         Rect textRect;
  351.         HLock(theText);
  352.         HUnlock(theText);
  353.         textRect = drawIt->portRect;
  354.         InsetRect(&textRect, 20, 20);
  355.         TETextBox(*theText, GetHandleSize(theText), &textRect, 0);
  356.         ReleaseResource(theText);
  357.     }
  358.     DrawControls(drawIt);
  359.     EndUpdate(drawIt);
  360.     SetPort(tempWP);
  361. }
  362.  
  363. /* my menu action taker.It returns a Boolean which I usually ignore, but it */
  364. /* mught be handy someday */
  365. Boolean DoSelected(long val)
  366. {
  367.     short loval, hival;
  368.     Boolean returnVal = false;
  369.     loval = LoWord(val);
  370.     hival = HiWord(val);
  371.     
  372.     switch (hival) {                                        /* switch off the menu number selected */
  373.         case kAppleMenu:                                    /* Apple menu */
  374.             if (loval != 1) {                               /* if this was not About, it's a DA */
  375.                 DoDaCall(gAppleMenuHandle, loval);
  376.             } else {
  377.                 Alert(kAboutBox, nil);                      /* do about box */
  378.             }
  379.             returnVal = true;
  380.             break;
  381.         case kFileMenu:                                     /* File menu */
  382.             switch (loval) {
  383.                 case kQuitItem:
  384.                     gQuit = true;                           /* onlyitem */
  385.                     returnVal = true;
  386.                     break;
  387.                 default:
  388.                     break;
  389.             }
  390.             break;
  391.             
  392.         case kEditMenu:
  393.             /* edit menu junk */
  394.             /* don't care */
  395.             break;
  396.             
  397.         case kToolsMenu:
  398.             /* add all your test stuff here */
  399.             if (gModalUp)
  400.                 CloseMovable();
  401.             else
  402.                 OpenMovable();
  403.             break;
  404.             
  405.         case kHMHelpMenuID:                                 /* Defined in Balloons.h */
  406.             /* I only care about this item.If anything else is returned here, I don't know what */
  407.             /* it is, so I leave it alone.Remember, the Help Manager chapter says that */
  408.             /* Apple reserves the right to add and change things in the Help menu */
  409.             if (loval == gHelpItem)
  410.                 SampleHelpDialog();
  411.             break;
  412.             
  413.     }
  414.     HiliteMenu(0);
  415.     return(returnVal);
  416. }
  417.  
  418. /* InitAEStuff installs my appleevent handlers */
  419. void InitAEStuff(void)
  420. {    
  421.     OSErr aevtErr = noErr;
  422.     long aLong = 0;
  423.     Boolean gHasAppleEvents = false;
  424.     /* Check this machine for AppleEvents.  If they are not here (ie not 7.0)
  425.     *   then we exit */
  426.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  427.     /* The following series of calls installs all our AppleEvent Handlers.
  428.     *   These handlers are added to the application event handler list that 
  429.     *   the AppleEvent manager maintains.  So, whenever an AppleEvent happens
  430.     *   and we call AEProcessEvent, the AppleEvent manager will check our
  431.     *   list of handlers and dispatch to it if there is one.
  432.     */
  433.     if (gHasAppleEvents) {
  434.          aevtErr = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, 
  435.              NewAEEventHandlerProc(AEOpenHandler),0, false);
  436.              if (aevtErr)  ExitToShell();
  437.  
  438.          aevtErr = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, 
  439.              NewAEEventHandlerProc(AEOpenDocHandler),0, false);
  440.              if (aevtErr)  ExitToShell();
  441.  
  442.          aevtErr = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, 
  443.              NewAEEventHandlerProc(AEQuitHandler), 0, false);
  444.              if (aevtErr)  ExitToShell();
  445.  
  446.          aevtErr = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, 
  447.              NewAEEventHandlerProc(AEPrintHandler),0, false);
  448.              if (aevtErr)  ExitToShell();
  449.  
  450.        } 
  451.     else ExitToShell();
  452.     
  453. }
  454. /* end InitAEStuff */
  455.  
  456. /* I'm not doing error handling in this sample for clarities sake, you should. Hah, */
  457.  
  458.  
  459. /* easy for me to say, huh? */
  460. void DoHighLevel(EventRecord *AERecord)
  461. {
  462.     
  463.     AEProcessAppleEvent(AERecord);
  464.     
  465. }
  466.  
  467. /* end DoHighLevel */
  468.  
  469. /* This is the standard Open Application event.*/
  470. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  471. {
  472. #pragma unused (messagein,reply,refIn)
  473.     Str255 theName;
  474.     WindowPtr myWindow, secondWindow;
  475.     /* we of course don't do anything here in this simple app */
  476.     /* except open our window */
  477.     myWindow = GetNewWindow(128, nil, (WindowPtr)-1);
  478.     ((WindowPeek)myWindow)->windowKind = kMyDocumentKind;
  479.     /* install drawing proc */
  480.     SetWRefCon(myWindow, (long)DrawMain);
  481.     /* open another one, so we can demonstrate shuffling inhibiting */
  482.     secondWindow = GetNewWindow(128, nil, (WindowPtr)-1);
  483.     ((WindowPeek)secondWindow)->windowKind = kMyDocumentKind;
  484.     /* install drawing proc */
  485.     SetWRefCon(secondWindow, (long)DrawMain2);
  486.     GetIndString(theName, kGenStrings, 1);
  487.     SetWTitle(secondWindow, theName);
  488.     SelectWindow(myWindow);
  489.     SetPort(myWindow);
  490.     return(noErr);
  491.     
  492. }
  493.  
  494. /* end AEOpenHandler */
  495.  
  496. /* Open Doc, opens our documents.Remember, this can happen at application start AND */
  497. /* anytime else.If your app is up and running and the user goes to the desktop, hilites one */
  498. /* of your files, and double-clicks or selects Open from the finder File menu this event */
  499. /* handler will get called. Which means you don't do any initialization of globals here, or */
  500. /* anything else except open then doc.*/
  501. /* SO-- Do NOT assume that you are at app start time in this */
  502. /* routine, or bad things will surely happen to you. */
  503.  
  504. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  505. {
  506. #pragma unused (messagein,refIn,reply)
  507.     /* we of course don't do anything here */
  508.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  509. }
  510.  
  511. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  512. {                                                           /* no printing handler in yet, so we'll ignore this */
  513.     /* the operation is functionally identical to the ODOC event, with the additon */
  514.     /* of calling your print routine.*/
  515. #pragma unused (messagein,refIn,reply)
  516.     /* we of course don't do anything here */
  517.     return(errAEEventNotHandled);                           /* we have no docs, so no pdoc events should come to us */
  518. }
  519.  
  520. /* Standard Quit event handler, to handle a Quit event from the Finder, for example.*/
  521. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life.*/
  522. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  523. {
  524. #pragma unused (messagein,refIn,reply)
  525.     
  526.     /* prepQuit sets the Stop flag for us.It does _NOT_ quit, you */
  527.     /* should NEVER quit from an AppleEvent handler.Calling */
  528.     /* ExitToShell here would blow things up */
  529.     gQuit = true;
  530.     return(noErr);
  531. }
  532.  
  533. /* This is my sample help dialog.Does not do anything, expand as you need */
  534. void SampleHelpDialog(void)
  535. {
  536.     DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1);
  537.     short itemhit = 0;
  538.     while (itemhit != 1) {
  539.         ModalDialog(nil, &itemhit);
  540.     }
  541.     DisposeDialog(tdial);
  542. }
  543.  
  544.  
  545. /* Opens the MModal dialog. */
  546. /* Just for grins, I'm also saving and restoring it's position in*/
  547. /* a very simple way */
  548. void OpenMovable(void)
  549. {
  550.     WindowPtr temp;
  551.     Str63 theWords;
  552.     temp = GetNewWindow(129, nil, (WindowPtr)-1);
  553.     /* install drawing proc */
  554.     SetWRefCon(temp, (long)DrawMovable);
  555.     
  556.     /* set the kind to my MModalwindow */
  557.     ((WindowPeek)temp)->windowKind = kMyModalKind;
  558.     gModalUp = true;
  559.     
  560.     /* add the go away button */
  561.     GetNewControl(kCloseButton, temp);
  562.     
  563.     /* change the menu item text */
  564.     GetIndString(theWords, kMenuToggleStrings, kCloseIt);
  565.     SetMenuItemText(gToolMenuHandle, kItem1, theWords);
  566.     
  567.     if (gSavedPos) {
  568.         /* move it to the saved position */
  569.         /* move it to 0,0 to avoid any math at all */
  570.         MoveWindow(temp, 0, 0, false);
  571.         MoveWindow(temp, gSavedPoint.h, gSavedPoint.v, false);
  572.     }
  573.     ShowWindow(temp);
  574.     /* kill all the menus except the Test, Help, and App */
  575.     DisableItem(gAppleMenuHandle, 0);
  576.     DisableItem(gFileMenuHandle, 0);
  577.     DisableItem(gEditMenuHandle, 0);
  578.     DrawMenuBar();
  579.     SetPort(temp);
  580. }
  581.  
  582. void CloseMovable(void)
  583. {
  584.     Str63 theWords;
  585.     WindowPtr temp = FrontWindow();
  586.     /* the front window really should be my modal window */
  587.     /* if it isn't, I'm bailing.*/
  588.     gSavedPos = true;
  589.     gSavedPoint.h = temp->portRect.left;
  590.     gSavedPoint.v = temp->portRect.top;
  591.     LocalToGlobal(&gSavedPoint);
  592.     if (((WindowPeek)temp)->windowKind == kMyModalKind)
  593.         CloseWindow(temp);
  594.     else
  595.         gQuit = true;
  596.     
  597.     gModalUp = false;
  598.     
  599.     /* reset the menu item text */
  600.     GetIndString(theWords, kMenuToggleStrings, kOpenIt);
  601.     SetMenuItemText(gToolMenuHandle, kItem1, theWords);
  602.     /* turn our menus back on */
  603.     EnableItem(gAppleMenuHandle, 0);
  604.     EnableItem(gFileMenuHandle, 0);
  605.     EnableItem(gEditMenuHandle, 0);
  606.     DrawMenuBar();
  607. }
  608.  
  609. /* Dim the MModal button when we go into the background */
  610. void SetModalButtonState(Boolean gInBackground)
  611. {
  612.     WindowPtr theWindow = FrontWindow();
  613.     ControlHandle theControl;
  614.     short hState;
  615.     if (gModalUp) {
  616.         /* only if we exist, o' course */
  617.         if (((WindowPeek)theWindow)->windowKind == kMyModalKind) {
  618.             /* if this isn't true, then things are weird */
  619.             hState = (gInBackground ? 255 : 0);
  620.             theControl = ((WindowPeek)theWindow)->controlList;
  621.             HiliteControl(theControl, hState);
  622.             
  623.         }
  624.     }
  625. }
  626.  
  627.  
  628.  
  629. #pragma segment Initialize
  630. void InitalizeApp(void)
  631. {
  632.     MenuHandle helpHandle;
  633.     Handle myMenu;
  634.     StringHandle helpString;
  635.     short count;
  636.     long vers;
  637.     MaxApplZone();
  638.     InitGraf((Ptr)&qd.thePort);
  639.     InitFonts();
  640.     InitWindows();
  641.     InitMenus();
  642.     TEInit();
  643.     InitDialogs(nil);
  644.     InitCursor();
  645.     /* Check system version */
  646.     Gestalt(gestaltSystemVersion, &vers);
  647.     vers = (vers >> 8) & 0xf;                               /* shift result over and mask out major version number */
  648.     if (vers < 7) {
  649.         StopAlert(kBadSystem, nil);
  650.         ExitToShell();
  651.     }
  652.     InitAEStuff();
  653.     /* set up my menu junk */
  654.     myMenu = GetNewMBar(kMBarID);
  655.     SetMenuBar(myMenu);
  656.     gAppleMenuHandle = GetMenuHandle(kAppleMenu);
  657.     gFileMenuHandle = GetMenuHandle(kFileMenu);
  658.     gEditMenuHandle = GetMenuHandle(kEditMenu);
  659.     gToolMenuHandle = GetMenuHandle(kToolsMenu);
  660.     AppendResMenu(gAppleMenuHandle, 'DRVR');
  661.     /* now install my Help menu item in the Help Manager's menu */
  662.     HMGetHelpMenuHandle(&helpHandle);                       /* Get the Hlpe menu handle */
  663.     count = CountMItems(helpHandle);                        /* How many items are there? */
  664.     helpString = GetString(kHelpString);                    /* get my help string */
  665.     DetachResource(helpString);                             /* detach it */
  666.     HNoPurge(helpString);
  667.     MoveHHi((Handle)helpString);
  668.     HLock((Handle)helpString);
  669.     InsertMenuItem(helpHandle, (Ptr)*helpString, count + 1);       /* insert my item in the Help menu */
  670.     gHelpItem = CountMItems(helpHandle);                    /* The number of the item */
  671.     
  672.     DrawMenuBar();
  673.     GetCurrentProcess(&gOurSN);                             /* Get our process serial number for later use, if needed */
  674.     
  675. }
  676.